package com.zifeng.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zifeng.common.Constant;
import com.zifeng.common.R;
import com.zifeng.dao.AssignmentDao;
import com.zifeng.feign.BlockFeignClient;
import com.zifeng.feign.OrderFeignClient;
import com.zifeng.pojo.Assignment;
import com.zifeng.pojo.Order;
import com.zifeng.pojo.Ship;
import com.zifeng.service.IAssignmentService;
import com.zifeng.utils.PageUtils;
import com.zifeng.utils.RedisUtils;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.zifeng.constant.RedisConstants.*;


/**
 * 船舶委托Controller
 *
 * @author zifeng
 * @date 2025-03-27
 */
@RestController
@RequestMapping("/assignment")
public class AssignmentController {
    @Autowired
    private IAssignmentService assignmentService;

    @Autowired
    private AssignmentDao assignmentDao;

    @Resource
    private OrderFeignClient orderFeignClient;

    @Resource
    private BlockFeignClient blockFeignClient;

    @Autowired
    private RedisUtils redisUtils;

    @GetMapping("/finishedlist")
    public R getFinishedAssignments() throws JsonProcessingException {
        QueryWrapper<Assignment> wrapper = new QueryWrapper<>();
        wrapper.eq("status", Constant.AssignmentStatus.FINISHED);
        List<Assignment> assignments = assignmentDao.selectList(wrapper);
        List<Assignment> finishedList = assignments.stream().filter(item -> item.getStatus() == 1).collect(Collectors.toList());
        String json = JSON.toJSONString(finishedList);
        return R.ok().put("finishedList", json);
    }

    @RequestMapping("/count")
    public R count() {
        Long count = assignmentDao.selectCount(null);
        return R.ok().put("count", count);
    }

    // 接受委托
    @RequestMapping("/agree/{id}")
    public R agreeAssignment(@PathVariable("id") int id, @RequestParam int clientId) {
       assignmentService.aggregateAssignments(id, clientId);

        return R.ok();
    }


    @RequestMapping("/listByFuzzyQuery")
    public R listByFuzzyQuery(@RequestParam Map<String, String> params) throws IOException {

        String data = params.get("data");
        if (StringUtils.isEmpty(data)) {
            return R.error(401, "查询参数不能为空");
        }
        ObjectMapper om = new ObjectMapper();
        Assignment assignment = om.readValue(data, Assignment.class);
        List<Assignment> list = assignmentDao.fuzzyQuery(assignment);
        list = judgeDate1(assignment.getBeginDate(), assignment.getEndDate(), list);
        list = judgeDate2(assignment.getCreateAt(), assignment.getUpdateAt(), list);
        int currPage = Integer.parseInt(params.get("page"));
        int pageSize = Integer.parseInt(params.get("limit"));
        PageUtils page = new PageUtils(list, list.size(), pageSize, currPage);
        return R.ok().put("page", page);
    }

    private static List<Assignment> judgeDate1(Date beginDate, Date endDate, List<Assignment> list) {
        // 日期判断
        List<Assignment> resList = new ArrayList<>();
        if (beginDate != null && endDate == null) {
            for (Assignment item : list) {
                int res = item.getBeginDate().compareTo(endDate);
                if (res == 1 || res == 0) {
                    resList.add(item);
                }
            }
            list = new ArrayList<>(resList);
        }else if (beginDate == null && endDate != null) {
            for (Assignment item : list) {
                int res = item.getEndDate().compareTo(endDate);
                if (res == -1 || res == 0) {
                    resList.add(item);
                }
                list = new ArrayList<>(resList);
            }
        } else if (beginDate != null && endDate != null) {
            for (Assignment item : list) {
                int res1 = item.getBeginDate().compareTo(beginDate);
                int res2 = item.getEndDate().compareTo(endDate);
                if ((res1 == 1 || res1 == 0) && (res2 == -1 || res2 == 0)) {
                    resList.add(item);
                }
            }
            list = new ArrayList<>(resList);
        }
        return list;
    }

    private static List<Assignment> judgeDate2(Date beginDate, Date endDate, List<Assignment> list) {
        // 日期判断
        List<Assignment> resList = new ArrayList<>();
        if (beginDate != null && endDate == null) {
            for (Assignment item : list) {
                int res = item.getCreateAt().compareTo(beginDate);
                if (res == 1 || res == 0) {
                    resList.add(item);
                }
            }
            list = new ArrayList<>(resList);
        }else if (beginDate == null && endDate != null) {
            for (Assignment item : list) {
                Date updateAt = item.getUpdateAt();
                if(updateAt == null) {
                    resList.add(item);
                }else {
                    int res = updateAt.compareTo(endDate);
                    if (res == -1 || res == 0) {
                        resList.add(item);
                    }
                }
                list = new ArrayList<>(resList);
            }
        } else if (beginDate != null && endDate != null) {
            for (Assignment item : list) {
                int res1 = item.getCreateAt().compareTo(beginDate);
                Date updateAt = item.getUpdateAt();
                if(updateAt == null && (res1 == 1 || res1 == 0)) {
                    resList.add(item);
                }else {
                    int res2 = updateAt.compareTo(endDate);
                    if ((res1 == 1 || res1 == 0) && (res2 == -1 || res2 == 0)) {
                        resList.add(item);
                    }
                }
            }
            list = new ArrayList<>(resList);
        }
        return list;
    }

    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params) {
        String page = (String) params.get("page");
        String size = (String) params.get("limit");
        int pageInt = Integer.parseInt(page);
        String pageKey = ASSIGNMENT_PAGE_PREFIX + page + ASSIGNMENT_PAGE_SIZE_PREFIX + size;
        // 只缓存前三页数据
        if(pageInt > 0 && pageInt < 3) {
            String assignmentListJson = redisUtils.getHash(pageKey, ASSIGNMENT_PAGE_LIST);
            if (!assignmentListJson.isEmpty()) {
                List<Assignment> assignments = JSON.parseArray(assignmentListJson, Assignment.class);
                int totalCount = Integer.parseInt(redisUtils.getHash(pageKey, ASSIGNMENT_PAGE_TOTAL));
                PageUtils pageUtils = new PageUtils(assignments, totalCount, Integer.parseInt(page), Integer.parseInt(size));
                return R.ok().put("page", pageUtils);
            }
        }

        PageUtils pageUtils = assignmentService.queryPage(params);
        if(pageInt > 0 && pageInt < 3) {
            redisUtils.setHash(pageKey, ASSIGNMENT_PAGE_LIST, JSON.toJSONString(pageUtils.getList()), ASSIGNMENT_PAGE_TTL, TTL_TIME_UNIT);
            int totalCount = pageUtils.getTotalCount();
            redisUtils.setHash(pageKey, ASSIGNMENT_PAGE_TOTAL, String.valueOf(totalCount), ASSIGNMENT_PAGE_TTL, TTL_TIME_UNIT);
        }
        return R.ok().put("page", pageUtils);
    }

    /**
     * 获取委托详细信息
     */
    @GetMapping(value = "/{id}")
    public R getInfo(@PathVariable("id") Long id) {
        Assignment assignment = assignmentService.selectAssignmentById(id);
        return R.ok().put("assignment", assignment);
    }

    /**
     * 新增委托
     */
    @PostMapping
    public R add(@RequestBody Assignment assignment) {
        assignmentService.insertAssignment(assignment);
        return R.ok();
    }

    /**
     * 修改委托
     */
    @PutMapping
    public R update(@RequestBody Assignment assignment) {
        assignmentService.updateAssignment(assignment);
        return R.ok().put("assignment", assignment);
    }

    /**
     * 删除委托
     */
    @DeleteMapping("/{ids}")
    public R remove(@PathVariable Long[] ids) {
        assignmentService.deleteAssignmentByIds(ids);
        return R.ok();
    }
}
